\section{algorithm}
算法库提供大量用途的函数（例如查找、排序、计数、操作），它们在元素范围上操作。注意范围定义为 [first, last) ，其中 last 指代要查询或修改的最后元素的后一个元素。算法头文件<algorithm>
\subsection{不修改容器中的元素}
\begin{table}[!htbp]
    \caption{不修改容器中的元素}
    \begin{tabular}{p{0.3\textwidth}p{0.7\textwidth}}
        \toprule
        标准函数                & 函数功能说明                                                                                                                      \\
        \midrule
        all\_of(C++11)          & 对于容器中所有元素使用条件测试                                                                                                    \\
        any\_of(C++11)          & 测试容器中元素是否有任何一个满足条件                                                                                              \\
        none\_of(C++11)         & 测试容器中所有元素是否同时不满足条件                                                                                              \\
        range::all\_of(C++20)   & 对于容器中所有元素使用条件测试                                                                                                    \\
        range::any\_of(C++20)   & 测试容器中元素是否有任何一个满足条件                                                                                              \\
        range::none\_of(C++20)  & 测试容器中所有元素是否同时不满足条件                                                                                              \\
        for\_each(C++11)        & 将函数应用到每一个元素                                                                                                            \\
        range::for\_each(C++11) & 将函数应用到每一个元素                                                                                                            \\
        find                    & 在容器中查找某个元素（只查找第一个），返回指向元素的迭代器，否则返回超尾迭代器。                                                  \\
        find\_if                & 在容器中查找指定条件的元素（只查找第一个），返回指向元素的迭代器如果找不到元素则返回超尾迭代器。                                  \\
        find\_if\_not           & 在容器中查找不满足指定条件的元素（只查找第一个），返回指向元素的迭代器，如果找不到元素则返回超尾迭代器。                          \\
        range::find             & 在容器中查找某个元素（只查找第一个），返回指向元素的迭代器，否则返回超尾迭代器。                                                  \\
        range::find\_if         & 在容器中查找指定条件的元素（只查找第一个），返回指向元素的迭代器如果找不到元素则返回超尾迭代器。                                  \\
        range::find\_if\_not    & 在容器中查找不满足指定条件的元素（只查找第一个），返回指向元素的迭代器，如果找不到元素则返回超尾迭代器。                          \\
        find\_end               & 在容器a中查找容器b，如果找到则返回指向容器b的第一个元素的迭代器否则返回超尾迭代器                                                 \\
        range::find\_end        & 在容器a中查找容器b，如果找到则返回指向容器b的第一个元素的迭代器否则返回超尾迭代器                                                 \\
        find\_first\_of         & 在一个容器中查找第一个等于另一个容器中的元素，返回指向第一个元素的迭代器否则返回超尾迭代器                                        \\
        adjacent\_find          & 在容器a指定的返回查找两次连续出现的元素，返回指向元素首位的迭代器。                                                               \\
        count                   & 查找容器中指定元素出现的次数。                                                                                                    \\
        count\_if               & 返回指定条件元素出现的次数。                                                                                                      \\
        mismatch                & 在容器a中查找不匹配容器b中的元素，返回pair<iterator,value>其中iterator表示第一个迭代器指向的位置，val表示第二个迭代器指向的位置。 \\
        \bottomrule
    \end{tabular}
\end{table}
\begin{cpp}
    #include <algorithm>
    #include <iostream>
    #include <vector>
    using namespace std;
    int main() {
    vector<int> a = {1, 3, 5, 7, 9};
    vector<int> b = {5, 5, 7, 8, 10};
    auto exists = std::any_of(a.begin(), a.end(),
    [](int a) { return a >= 2; }); //是否存在一个元素>=2
    auto all_ex = std::all_of(a.begin(), a.end(),
    [](int a) { return a >= 2; }); //是否所有元素都>=2
    auto all_max = std::none_of(a.begin(), a.end(), [](int a) {
            return a >= 10;
        });                                   //是否所有元素同时不满足a>=10
    cout << boolalpha << exists << endl;  // true
    cout << boolalpha << all_ex << endl;  // false
    cout << boolalpha << all_max << endl; // true
    std::for_each(a.begin(), a.end(),
    [](int a) { return a + 1; }); // 容器中所有元素+1,无法修改a

    auto it = std::find(a.begin(), a.end(), 3);
    if (it == a.end())
    cout << "没有找到元素" << endl;
    else
    cout << *it << endl;
    it = std::find_if(a.begin(), a.end(), [](int a) {
            return a > 5;
        }); //找到第一个大于5的元素的迭代器
    cout << *it << endl;
    it = std::find_if_not(a.begin(), a.end(), [](int a) {
            return a == 5;
        }); //找到第一个不等于5的元素1
    cout << *it << endl;
    it = std::find_first_of(a.begin(), a.end(), b.begin(),
    b.end()); //在容器a中找到第一个={5,5,7,8,10}的元素
    cout << *it << " next" << *(it + 1) << endl;
    it = std::adjacent_find(b.begin(), b.end()); //容器b中连续出现两次的元素5
    cout << *it << endl;
    cout << "5 出现的次数:" << std::count(b.begin(), b.end(), 5)
    << endl; // 5出现的次数2
    cout << std::count_if(b.begin(), b.end(),
    [](int a) { return a > 5; }); //>5的元素出现的次数3
    cout << boolalpha
    << std::equal(a.begin(), a.end(), b.begin(),
    b.end()); //容器a和b中的元素是否完全相等
    }
\end{cpp}
\begin{table}[!htbp]
    \centering
    \begin{tabular}{cc}
        \toprule
        函数名称        & 说明                                                         \\
        \midrule
        equal           & 比较两个容器中的元素是否完全相同。返回bool的比较结果。       \\
        is\_permutation & 测试一个容器是否是另一个容器的全排序列之一。                 \\
        search          & 在容器a中搜索容器b第一次出现的位置。找不到则返回超尾迭代器。 \\
        range::search   & 在容器a中搜索容器b第一次出现的位置。找不到则返回超尾迭代器。 \\
        search\_n       & 在容器a中搜索元素n出现c次的结果。                            \\
        \bottomrule
    \end{tabular}
\end{table}
\begin{cpp}
    #include <algorithm>
    #include <iostream>
    #include <vector>
    using namespace std;
    int main() {
    vector<int> a = {1, 3, 5, 7, 9, 1, 3};
    vector<int> b = {1, 3};
    cout << boolalpha
    << std::is_permutation(a.begin(), a.end(),
    b.begin())
    << endl; // 容器a中的元素是否为b中元素的全排列。
    auto it = std::search(a.begin(), a.end(), b.begin(),
    b.end()); //在 a 中找到第一个1,3所在的位置
    cout << *it << " locate:" << std::distance(it, a.begin())
    << endl; //在a中找到最后一个1,3所在位置

    it = std::find_end(a.begin(), a.end(), b.begin(), b.end());
    cout << *it << " locate:" << std::distance(a.begin(), it) << endl;
    }

\end{cpp}
\begin{cpp}
    #include <algorithm>
    #include <functional>
    #include <iostream>
    #include <iterator>
    #include <numeric>
    #include <vector>
    namespace ranges = std::ranges;
    int main() {
    std::vector<int> v(10, 2);
    std::cout << "原始的vector元素：";
    ranges::copy(
    v, std::ostream_iterator<int>(std::cout, " ")); // 2 2 2 2 2 2 2 2 2 2
    std::partial_sum(v.cbegin(), v.cend(), v.begin());
    std::cout << "累计求和后的所有的成员: ";
    ranges::copy(v, std::ostream_iterator<int>(std::cout,
    " ")); // 2 4 6 8 10 12 14 16 18 20
    std::cout << '\n';

    if (ranges::all_of(v.cbegin(), v.cend(), [](int i) { return i % 2 == 0; })) {
            std::cout << "所有的元素均为偶数";
        }
    if (ranges::none_of(
    v, std::bind(std::modulus<int>(), std::placeholders::_1, 2))) {
            std::cout << "所有的元素均为奇数\n";
        }

    auto DivisibleBy = [](int d) { return [d](int m) { return m % d == 0; }; };

            if (ranges::any_of(v, DivisibleBy(7))) {
                    std::cout << "至少有一个元素能被 7 整除\n";
                }
        }

\end{cpp}
\subsection{修改容器中的元素}
\begin{table}[!htbp]
    \caption{修改容器的元素}
    \begin{tabular}{p{0.2\textwidth}p{0.8\textwidth}}
        \toprule
        函数              & 函数说明                                                                                         \\
        \midrule
        copy              & 拷贝容器a中的元素到容器b中(如果a中指定的区域包含的元素大于b，则只拷贝b.size()个元素)             \\
        copy\_n           & 拷贝容器a中的n个元素到容器b中                                                                    \\
        copy\_if          & 拷贝容器a中的符合条件的元素到容器b中。                                                           \\
        copy\_backward    & 同样是拷贝一个容器中的元素到另一个容器，但是copy的时候是将copy元素从后往前一个个移动到目的位置。 \\
        move              & 将容器a中指定范围的元素移动到容器b中。                                                           \\
        move\_backward    & 将容器a中指定范围的元素移动到容器b中，移动的时候按照从后往前的方式移动。                         \\
        swap              & 交换两个容器里面的元素。                                                                         \\
        swap\_ranges      & 交换容器a中指定位置的元素到b指定的位置。                                                         \\
        iter\_swap        & 交换迭代器指向的内容                                                                             \\
        transform         & 对于容器a中的每个元素，执行操作然后将结果存放到b容器迭代器指向的位置。                           \\
        replace           & 将容器a中指定的值替换成另一个值                                                                  \\
        replace\_if       & 如果容器a中的元素满足条件则替换                                                                  \\
        replace\_copy     & copy容器a指定的元素使用b中的元素替换（和replace一样，只是指定的数据范围）                        \\
        replace\_copy\_if & copy容器a中指定范围的元素到容器b中，replace其中需要替换的值（和replace\_if一样，添加了范围）     \\
        fill              & 用指定的元素填充容器（填充范围通过迭代器指定）                                                   \\
        fill\_n           & 填充元素从filll的迭代器指定的范围变成迭代器+元素个数的方式。                                     \\
        \bottomrule
    \end{tabular}
\end{table}
\begin{cpp}
    #include <algorithm>
    #include <iostream>
    #include <utility>
    #include <vector>
    using namespace std;
    void showVec(vector<int> elem) {
            for (auto e : elem)
            cout << e << " ";
            cout << endl;
        }
    int main() {
    vector<int> a = {1, 3, 5, 7, 9};
    vector<int> b = vector<int>(6, 0);
    std::copy(a.begin(), a.begin() + 2, b.begin()); // 1 3 0 0 0 0
    std::copy_n(a.begin(), 3, b.begin());           // 1,3,5,0,0,0
    std::copy_if(a.begin(), a.end(), b.begin(),
    [](int a) { return a > 4; }); // 5 7 9 0 0 0
    std::copy_backward(a.begin(), a.begin() + 3,
    b.end()); // 5 7 9 1 3 5 (1,3,5)放到b的末尾
    std::move(a.begin(), a.begin() + 3, b.begin());
    a = std::move(b); // b的元素为空，来源于utility
    cout << a.size() << " " << b.size() << endl; // 6 0
    b = vector<int>(6, 0);
    std::move_backward(a.begin(), a.begin() + 3, b.end()); // 0 0 0 1 3 5
    std::swap(a, b); // a:0 0 0 1 3 5 b:1 3 5 1 3 5
    std::swap_ranges(a.begin(), a.begin() + 3,
    b.begin() + 1);        // a:3 5 1 1 3 5 b:1 0 0 0 3 5
    std::iter_swap(a.begin(), b.end() - 1); // a:5 5 1 1 3 5,b:1 0 0 0 3 3
    std::transform(a.begin(), a.end(), b.begin() + 1,
    [](int a) { return a + 1; });            // b:1 6 6 2 2 4
    std::replace(b.begin(), b.begin() + 1, *b.begin(), 99); // b:99 6 6 2 2 4
    std::replace_if(
    b.begin(), b.end(), [](int a) { return (a % 2) == 1; },
    0); // b:0 6 6 2 2 4
    std::replace_copy(a.begin(), a.begin() + 3, b.begin(), 5,
    3); // a:5 5 1 1 3 5 b:5 5 1 1 3 5
    showVec(a);
    showVec(b);
    std::replace_copy_if(
    a.begin(), a.end(), b.begin(), [](int a) { return a % 2 == 1; },
            7);                                 // b:7 7 7 7 7 7
            std::fill(b.begin(), b.begin() + 3, 5); // b:5 5 5 7 7 7
            std::fill_n(b.begin(), 3, 6);           // b:6 6 6 7 7 7
        }
\end{cpp}
\begin{table}[!htbp]
    \centering
    \caption{修改容器的元素}
    \begin{tabular}{p{0.2\textwidth}p{0.8\textwidth}}
        \toprule
        generate         & 按照指定规则生成容器中的元素                                                                             \\
        \midrule
        generate\_n      & 按照指定规则生成容器中的元素，生成方式从迭代器范围变成了迭代器+元素个数的方式。                          \\
        remove           & 从容器中移除指定元素（空位位置由后面的元素依次填充然后末尾空位由最后一个元素填充）                       \\
        remove\_if       & 从容器中移除符合条件的元素，不符合条件的元素依次顺序放入容器，移除容器导致的的空位由原先存在的元素保持。 \\
        remove\_copy     & 将容器中指定条件的元素删除然后将删除后的结果copy到另一个容器中。                                         \\
        remove\_copy\_if & 将容器a中的元素删除然后将符合条件的元素copy到另一个容器中。                                              \\
        unique           & 删除容器中的重复元素                                                                                     \\
        unique\_copy     & 删除容器中重复元素然后将删除后的结果移动到另一个容器中                                                   \\
        reverse          & 反转容器中的元素                                                                                         \\
        reverse\_copy    & 反转容器中的元素然后将反转后的的元素复制到另一个容器中                                                   \\
        rotate           & 将容器中的元素沿着指定的位置旋转                                                                         \\
        rotate\_copy     & 将容器中的元素沿着指定的迭代器旋转，然后将结果存放在另一个容器中                                         \\
        random\_shuffle  & 将容器中迭代器指定范围的元素随机打乱                                                                     \\
        shuffle          & 按照指定的随机方式生成容器中的元素。                                                                     \\
        \bottomrule
    \end{tabular}
    \label{tab:change_contain}
\end{table}
\begin{cpp}
    #include <iostream>
    #include <random>
    #include <utility>
    #include <vector>
    using namespace std;
    void showVec(vector<int> elem) {
            for (auto e : elem)
            cout << e << " ";
            cout << endl;
        }
    int f() {
            static int i = 0;
            return ++i;
        }
    int main() {
    vector<int> a = vector<int>(5);
    std::generate(a.begin(), a.end(), f); // a:1 2 3 4 5
    std::generate(a.begin(), a.end(),
    [n = 0]() mutable { return n++; }); // 0 1 2 3 4
    std::generate_n(a.begin(), 4,
    [n = 2]() mutable { return n++; }); // a:2 3 4 5 4
    std::remove(a.begin(), a.end(), 5);                 // a:2 3 4 4 4
    std::remove_if(a.begin(), a.end(),
    [](int a) { return a % 2 == 1; }); // a:2 4 4 4 4
            vector<int> b = vector<int>(5);
            std::remove_copy_if(a.begin(), a.end(), b.begin(),
            [](int a) { return a == 4; }); // b:2 0 0 0 0
            std::unique(a.begin(),
            a.end()); // a:2 4 4 4 4去重后为 2 4然后填充最后一个元素4
            vector<int> c = vector<int>(6);
            std::unique_copy(
            a.begin(), a.end(),
            c.begin()); // c:2 4 0 0 0 0 去重后结果 2 4,然后填充最后一个元素0
            std::reverse(c.begin(), c.begin() + 2);                 // c:4 2 0 0 0 0
            std::reverse_copy(c.begin(), c.begin() + 2, b.begin()); // b:2 4 0 0 0
            std::rotate(a.begin(), a.begin() + 3, a.end());         // a:4 4 2 4 4
            std::rotate_copy(a.begin(), a.begin() + 2, a.end(),
            b.begin()); // a不变，结果放在b：2 4 4 4 4
            vector<int> d = vector<int>(10);
            std::generate(d.begin(), d.end(), [n = 0]() mutable { return ++n; });
            std::random_shuffle(d.begin(), d.end()); // d:5 4 8 9 1 6 3 2 7 10
            int seed = 1;
            std::shuffle(d.begin(), d.end(),
            std::default_random_engine(
            seed)); // d:8 2 4 3 7 5 1 10 6 9
            // 设置随机初始化种子保证每次生成的结果不变
            showVec(d);
        }
\end{cpp}
\begin{table}[!htbp]
    \caption{Partion}
    \begin{tabular}{p{0.2\textwidth}p{0.8\textwidth}}
        \toprule
        函数              & 说明                                                     \\
        is\_partitioned   & 容器中的元素是否按照指定的规则分组                       \\
        \midrule
        partition         & 将容器中的元素按照指定的规则分组                         \\
        stable\_partition & 按照指定的规则分组的同时保证原来的元素相对位置不变       \\
        partition\_copy   & 按照指定规则对数据分组同时将分组后的结果存放在新的容器中 \\
        partition\_point  & 将容器中的元素分组后，返回分组点的迭代器。               \\
        \bottomrule
    \end{tabular}
\end{table}
\begin{cpp}
    #include <algorithm>
    #include <iostream>
    #include <random>
    #include <utility>
    #include <vector>
    using namespace std;
    void showVec(vector<int> elem) {
            for (auto e : elem)
            cout << e << " ";
            cout << endl;
        }
    bool isOdd(int n) { return n % 2 == 1; }
    int main() {
            vector<int> a = vector<int>(10);
            std::generate(a.begin(), a.end(), [n = 0]() mutable { return ++n; });
            cout << boolalpha
            << std::is_partitioned(a.begin(), a.end(), isOdd); // false：没有分组
            std::partition(a.begin(), a.end(), isOdd);
            showVec(a);
            cout << boolalpha
            << std::is_partitioned(a.begin(), a.end(), isOdd); // true：有分组
            std::stable_partition(a.begin(), a.end(),
            [](int a) { return a > 3; }); // a:9 7 5 6 4 8 10 1 3 2
            vector<int> greater = vector<int>(10);
            vector<int> smaller = vector<int>(10);
            std::partition_copy(a.begin(), a.end(), greater.begin(), smaller.begin(),
            [](int a) { return a > 4; });

            showVec(greater); // greater:9 7 5 6 8 10 0 0 0 0
            showVec(smaller); // smaller:4 1 3 2 0 0 0 0 0 0
        }
\end{cpp}
\begin{table}[!htbp]
    \caption{排序}
    \begin{tabular}{p{0.2\textwidth}p{0.8\textwidth}}
        \toprule
        函数                & 说明                                                                         \\
        \midrule
        sort                & 排序容器中的元素                                                             \\
        stable\_sort        & 排序容器中的元素同时保证容器中元素的相对位置不变                             \\
        partial\_sort       & 排序容器中指定范围内的元素                                                   \\
        partial\_sort\_copy & 排序容器中指定范围的元素同时将排序结果copy到另一个容器(以目的容器的长度为准) \\
        is\_sorted          & 判断容器是否是排序过的。                                                     \\
        is\_sorted\_until   & 判断迭代器指定范围的元素是否排序过                                           \\
        nth\_element        & n元素左边元素均小于n迭代器指向的元素右边大于迭代器元素（默认排序的情况）     \\
        \bottomrule
    \end{tabular}
\end{table}
\begin{cpp}
    #include <algorithm>
    #include <iostream>
    #include <random>
    #include <utility>
    #include <vector>
    using namespace std;
    void showVec(vector<int> elem) {
            for (auto e : elem)
            cout << e << " ";
            cout << endl;
        }
    bool isOdd(int n) { return n % 2 == 1; }
    int main() {
            vector<int> data = vector<int>(10);
            std::generate(data.begin(), data.end(), [n = 0]() mutable { return n++; });
            std::shuffle(data.begin(), data.end(),
            std::default_random_engine(0)); // data:2 7 1 6 8 0 4 9 5 3
            std::partial_sort(
            data.begin(), data.begin() + 5,
            data.end()); //只对前5个元素降序排列 data: 0 1 2 3 4 8 7 9 6 5
            std::shuffle(data.begin(), data.end(), std::default_random_engine(0));
            showVec(data); // data:2 9 1 7 6 0 4 5 8 3
            std::partial_sort(data.begin(), data.begin() + 5, data.end(),
            std::greater<>()); // data:9 8 7 6 5 0 1 2 4 3
            vector<int> sorted = vector<int>(10);
            std::partial_sort_copy(
            data.begin(), data.begin() + 5, sorted.begin(), sorted.begin() + 5,
            std::greater<>()); // sorted：排序后的后5个元素放入sorted
            showVec(sorted);       // 5 6 7 8 9 0 0 0 0 0
            cout << boolalpha
            << std::is_sorted(sorted.begin(), sorted.end(),
            std::greater<>()); //判断是否是从大到小排序的。true
            std::shuffle(data.begin(), data.end(), std::default_random_engine(1));
            showVec(data);
            std::nth_element(
            data.begin(), data.begin() + 5,
            data.end()); // 2 1 0 4 3 5 6 9 8 7 前5个元素小于5后5个元素相反
            showVec(data);
        }

\end{cpp}
\begin{table}[!htbp]
    \caption{二分搜索（排序后的容器）}
    \begin{tabular}{p{0.2\textwidth}p{0.8\textwidth}}
        \toprule
        函数           & 说明                                                                    \\
        \midrule
        lower\_bound   & 返回指向小于指定值的迭代器（实际指向的是这个元素）                      \\
        upper\_bound   & 返回指向大于指定值的迭代器（实际指向的是这个元素的上一个元素）          \\
        equal\_range   & 返回pair<iter1,iter2>，iter1指向元素左边的位置，iter2指向元素右边的位置 \\
        binary\_search & 搜索指定元素，找到返回true，否则返回false                               \\
        \bottomrule
    \end{tabular}
\end{table}
\begin{cpp}
    #include <algorithm>
    #include <iostream>
    #include <random>
    #include <tuple>
    #include <utility>
    #include <vector>
    using namespace std;
    void showVec(vector<int> elem) {
            for (auto e : elem)
            cout << e << " ";
            cout << endl;
        }
    bool isOdd(int n) { return n % 2 == 1; }
    int main() {
    vector<int> data = vector<int>(10);
    std::generate(data.begin(), data.end(), [n = 0]() mutable { return n++; });
    auto it = std::lower_bound(data.begin(), data.end(), 6);
    cout << "小于6的元素:" << *it << " index:" << std::distance(data.begin(), it);
    it = std::upper_bound(data.begin(), data.end(), 7);
    cout << "大于7的元素:" << *it << " index:" << std::distance(data.begin(), it)
    << endl;
    vector<int> b = {1, 2, 3, 4, 4, 4, 7, 8};
    auto res = std::equal_range(b.begin(), b.end(), 4);
    auto first = b.begin(), second = b.begin();
    std::tie(first, second) = res;
    cout << "start index:" << std::distance(b.begin(), first)
    << " value: " << *first << endl;                                 // 3 4
    cout << boolalpha << std::binary_search(data.begin(), data.end(), 5); // true
    }
\end{cpp}
\begin{table}[!htbp]
    \caption{集合操作}
    \begin{tabular}{p{0.4\textwidth}p{0.6\textwidth}}
        \toprule
        函数                       & 说明                                                                                                                                                       \\
        \midrule
        merge                      & 融合两个迭代器指定范围的元素到一个新的迭代器指向的元素（新迭代的开始位置），融合的两个容器中的元素为升序或者降序的。（两个迭代器指向的数据段有序有序融合） \\
        inplace\_merge             & 融合两个已经排序的容器，不同点在于此时排序的容器是一个容器中的不同部分，融合后的容器依然为存放在本容器                                                     \\
        includes                   & 测试容器a中是否包含（无序也可）容器b中的元素                                                                                                               \\
        set\_union                 & 将两个有序容器中的元素去重然后放到新的容器中                                                                                                               \\
        set\_intersection          & 获取两个有序容器中的元素的交集然后将容器中的元素放到新的容器中                                                                                             \\
        set\_difference            & 获取容器a中和容器b中不相同的元素放在新的容器中                                                                                                             \\
        set\_symmetric\_difference & 排序两个容器中的元素（删除两个容器中的公共元素）返回指向新的容器的最后一个元素的迭代器。                                                                   \\
        \bottomrule
    \end{tabular}
\end{table}
\begin{cpp}
    #include <algorithm>
    #include <iostream>
    #include <random>
    #include <tuple>
    #include <utility>
    #include <vector>
    using namespace std;
    void showVec(vector<int> elem) {
            for (auto e : elem)
            cout << e << " ";
            cout << endl;
        }
    bool isOdd(int n) { return n % 2 == 1; }
    int main() {
    vector<int> data = vector<int>(10);
    std::generate(data.begin(), data.end(), [n = 0]() mutable { return n++; });
    vector<int> b = {1, 5, 3, 6, 8};
    vector<int> res = vector<int>(data.size() + b.size());
    std::sort(data.begin(), data.end());
    std::sort(b.begin(), b.end());
    std::merge(data.begin(), data.begin() + 4, b.begin(), b.end(),
    res.begin()); // res:0 1 1 2 3 3 5 6 8 0 0 0 0 0 0
    data = {1, 3, 5, 2, 4, 6, 8};
    std::inplace_merge(
    data.begin(), data.begin() + 3,
    data.end()); //[0,3)和[3,end)有序序列合并为一个有序序列,data:1 2 3 4 5 6 8
    vector<int> data1 = {1, 4, 6};
    cout << boolalpha
    << std::includes(data.begin(), data.end(), data1.begin(),
    data1.end()); // data 包含 data1,true
    data1 = {2, 4, 7};
    std::set_union(data.begin(), data.end(), data1.begin(), data1.end(),
    res.begin()); //容器 data 和 data1并集放到res:1 2 3 4 5 6 7 8 8
    // 0 0 0 0 0 0
    vector<int> res1 = vector<int>(5);
    vector<int> res2 = vector<int>(5);
    vector<int> res3;
    std::set_intersection(data.begin(), data.end(), data1.begin(), data1.end(),
    res1.begin()); //容器 data 和 data1的交集res：2 4 0 0 0
    std::set_difference(
    data.begin(), data.end(), data1.begin(), data1.end(),
    res2.begin()); // 容器 data 和 data1 的不同元素放在res2：1 3 5 6 8
    std::set_symmetric_difference(
    data.begin(), data.end(), data1.begin(), data1.end(),
    std::back_inserter(
    res3)); // 1 3 5 6 7 8 去除data和data1的重复元素插入res3
    }
\end{cpp}
\begin{table}[!htbp]
    \caption{堆操作}
    \begin{tabular}{p{0.2\textwidth}p{0.8\textwidth}}
        \toprule
        函数            & 说明                                 \\
        \midrule
        push\_heap      & 将指定元素放到堆上                   \\
        pop\_heap       & 从堆中弹出指定元素                   \\
        make\_heap      & 创建一个堆                           \\
        sort\_heap      & 排序堆里面的元素                     \\
        is\_heap        & 判断容器中的元素是否是一个堆         \\
        is\_heap\_until & 查找序列中违反最大堆条件的第一个元素 \\
        \bottomrule
    \end{tabular}
\end{table}
\begin{cpp}
    #include <algorithm>
    #include <iostream>
    #include <random>
    #include <tuple>
    #include <utility>
    #include <vector>
    using namespace std;
    void showVec(vector<int> elem) {
            for (auto e : elem)
            cout << e << " ";
            cout << endl;
        }
    bool isOdd(int n) { return n % 2 == 1; }
    int main() {
    vector<int> data = {1, 5, 7, 3, 8, 6, 4, 2};
    std::make_heap(data.begin(), data.end()); //构建最大堆 8 5 7 3 1 6 4 2
    data.push_back(9);
    std::push_heap(data.begin(),
    data.end()); //最大堆元素变成了9,元素：9 8 7 5 1 6 4 2 3
    cout << boolalpha << std::is_heap(data.begin(), data.end()); //是堆true
    std::sort_heap(data.begin(), data.end());                    //堆排序
    showVec(data);
    vector<int> res;
    std::make_heap(data.begin(), data.end());
    for (int i = 0; i < 2; i++) { //获取堆顶元素放入res
            std::pop_heap(data.begin(), data.end());
            res.push_back(data.back());
            data.pop_back();
        }
    showVec(res); // 9,8
    std::sort_heap(data.begin(), data.end());
    showVec(data);
    auto ill = std::is_heap_until(
    data.begin(),
    data.end()); //第一个违背最大堆规则的元素为2,它应该小于堆顶元素，此时堆顶元素为1
    cout << *ill;
    }
\end{cpp}
\begin{table}[!htbp]
    \caption{最值函数}
    \begin{tabular}{p{0.2\textwidth}p{0.8\textwidth}}
        \toprule
        函数            & 函数说明                                 \\
        \midrule
        min             & 返回容器中的最小元素                     \\
        max             & 返回容器中的最大元素                     \\
        minmax          & 返回容器中最小元素和最大元素的pair       \\
        min\_element    & 返回容器中最小元素的迭代器               \\
        max\_element    & 返回指向容器中最大元素的迭代器           \\
        minmax\_element & 返回指向容器中最小和最大元素的迭代器pair \\
        \bottomrule
    \end{tabular}
\end{table}
\begin{cpp}
    #include <algorithm>
    #include <iostream>
    #include <random>
    #include <tuple>
    #include <utility>
    #include <vector>
    using namespace std;
    void showVec(vector<int> elem) {
            for (auto e : elem)
            cout << e << " ";
            cout << endl;
        }
    bool isOdd(int n) { return n % 2 == 1; }
    int main() {
    vector<int> data = {1, 5, 7, 3, 8, 6, 4, 2};
    int minValue = std::min(5, 7); //小值5
    int maxValue = std::max(5, 7); //大值7
    int conMin, conMax;
    std::tie(conMin, conMax) = std::minmax(5, 7);
    auto it_min = data.begin(), it_max = data.begin();
    it_min = std::min_element(data.begin(), data.end());
    it_max = std::max_element(data.begin(), data.end());
    cout << "min:" << *it_min << " "
    << " max:" << *it_max;
    std::tie(it_min, it_max) = std::minmax_element(data.begin(), data.end());

    cout << "min:" << *it_min << " "
    << " max:" << *it_max;
    }
\end{cpp}
\begin{table}[!htbp]
    \caption{比较函数}
    \begin{tabular}{p{0.4\textwidth}p{0.6\textwidth}}
        \toprule
        \href{http://c.biancheng.net/view/595.html}{lexicographical\_compare} & 比较两个容器中的元素，比较的算法可以通过 lambda 表达式指定,默认是小于。返回bool结果。 \\
        \midrule
        next\_permutation                                                     & 获取容器中元素集合的全排的下一个组合，直到全排序列中最后序列。                        \\
        prev\_permutation                                                     & 获取容器中元素集合的全排的下一个组合，直到全排序列中的最前序列。                      \\
        is\_permutation                                                       & 判断迭代器指向的未知起是否是另一个字符串的全排列                                      \\
        \bottomrule
    \end{tabular}
\end{table}
\begin{cpp}
    #include <algorithm>
    #include <iostream>
    #include <random>
    #include <string>
    #include <tuple>
    #include <utility>
    #include <vector>
    using namespace std;
    void showVec(vector<int> elem) {
            for (auto e : elem)
            cout << e << " ";
            cout << endl;
        }
    int main() {
    string info = "abcd";
    std::sort(info.begin(), info.end());
    do {
            cout << "current:" << info << " \n";
        } while (std::next_permutation(info.begin(),
    info.end())); //获取全排列直到最后一个结果
    do {
            cout << "current:" << info << " \n";
        } while (std::prev_permutation(info.begin(),
    info.end())); //获取全排列直到最后一个结果
    string res = "abdc";
    cout << boolalpha
    << std::is_permutation(info.begin(), info.end(), res.begin());
    std::vector<string> s1 = {"I", "love", "cpp"};
    std::vector<string> s2 = {"also", "love", "python"};
    bool smaller_dict =
    std::lexicographical_compare(s1.begin(), s1.end(), s2.begin(), s2.end());
    std::cout << boolalpha << smaller_dict;
    }
\end{cpp}
\section{functional}
\begin{table}[!htbp]
    \centering
    \begin{tabular}{cc}
        \toprule
        函数                                                                   & 说明                                         \\
        \midrule
        \href{https://www.cplusplus.com/reference/functional/bind/}{bind}      & 实现对函数参数的绑定，类似于Python中的偏函数 \\
        \href{https://www.cplusplus.com/reference/functional/cref/}{cref}      & 将常量值或者refrence\_wrapper转换为它的拷贝  \\
        \href{https://www.cplusplus.com/reference/functional/mem_fn/}{men\_fn} & 转换成员函数为函数对象调用                   \\
        \href{https://www.cplusplus.com/reference/functional/not1/}{not1}      & 一元操作，用于将输入取反                     \\
        \href{https://www.cplusplus.com/reference/functional/not2/}{not2}      & 一元操作，将输入取反                         \\
        \href{https://www.cplusplus.com/reference/functional/ref/}{ref}        & 获取对象引用，其值变化引用对象的值也会变化。 \\
        \bottomrule
    \end{tabular}
\end{table}

\begin{itemize}
    \item \cppinline{std::bind(func,args)}：使用参数args绑定函数。其中（std::placehold::\_1表示func的第一个参数）。
          \begin{cpp}
              #include <functional>
              #include <iostream>
              using namespace std;
              int sum(int a, int b) { return a + b; }
              int main() {
                      auto bindFunc = bind(sum, std::placeholders::_1, 1);
                      cout << "3 + 1 = " << bindFunc(3);//相当于绑定 b 为1
                  }
          \end{cpp}
    \item \cppinline{std::cref(class)}：获取class的引用。\cppfile{sample/functional_cref_demo.cc}
    \item \cppinline{std::mem_fn}:把成员函数转化为函数对象是对象指针堆对象引用进行绑定。
          \begin{cpp}
              #include <functional>
              #include <iostream>
              using namespace std;
              class ClassA {
                      public:
                      void memberfunction() { std::cout << "调用无参数的成员函数" << std::endl; }

                      void memberfunction(int arg) {
                              std::cout << "调用有参数的构造函数，参数：" << arg << std::endl;
                          }
                  };

              int main() {
                      auto mem_fptr1 =
                      std::mem_fn(static_cast<void (ClassA::*)()>(&ClassA::memberfunction));
                      auto mem_fptr2 =
                      std::mem_fn(static_cast<void (ClassA::*)(int)>(&ClassA::memberfunction));
                      mem_fptr1(ClassA());
                      mem_fptr2(ClassA(), 3);
                  }

          \end{cpp}
    \item \cppinline{std::not1}：构造一个函数对象，返回输入函数对象结果的反。
          \cppfile{sample/functional_not1_demo.cc}
    \item \cppinline{std::not2}：\cppfile{sample/functional_not2_demo.cc}
    \item \cppinline{std::ref}：引用元素，引用结果和原始数据会变化，和 cref 不同在于返回的结果不是 const。\cppfile{sample/functional_ref_demo.cc}
\end{itemize}
\begin{table}[!htbp]
    \centering
    \caption{包装器类}
    \begin{tabular}{cc}
        \toprule
        函数                                                                                 & 说明                                     \\
        \midrule
        \href{https://www.cplusplus.com/reference/functional/binary_negate/}{binary\_negate} & 传入一个构造体，其作用于传入数据之后取反 \\
        \href{https://www.cplusplus.com/reference/functional/function/}{function}            & 包装任意可调用类型为可拷贝类型           \\
        \href{https://www.cplusplus.com/reference/reference_wrapper/}{regrence\_wrapper}     & 获取对象的引用                           \\
        \href{https://www.cplusplus.com/reference/functional/unary_negate/}{unray\_negate}   & 接收可调用对象作用于参数                 \\
        \bottomrule
    \end{tabular}
\end{table}
binray\_negate使用：
\cppfile{sample/functional_binary_negate_demo.cc}
function对象可以包装任何可调用对象为可拷贝对象，常见的对象为函数、函数指针、函数对象、lambda表达式、标准funtion对象。常见成员函数如下：
\begin{itemize}
    \item assign：赋值目标或者target
    \item operator=：检查是否可调用
    \item operator()：调用
    \item target\_type：目标的类型信息
    \item target：获取目标的指针
    \item swap：交换目标
\end{itemize}
\cppfile{sample/functional_function_demo.cc}
reference\_wrapper 获取对象的引用。
\cppfile{sample/functional_reference_wrapper_demo.cc}
unary\_negate：可以通过传入对象，通过对象作用于参数。
\cppfile{sample/functional_unary_negate.cc}
\begin{table}[!htbp]
    \centering
    \caption{常见的一元和二元操作}
    \begin{tabular}{cc}
        \toprule
        函数名称       & 说明         \\
        \midrule
        bit\_and       & 按位与       \\
        bit\_or        & 按位或       \\
        bit\_xor       & 按位异或     \\
        divides        & 除法         \\
        equal\_to      & 是否等于     \\
        greater        & 是否大于     \\
        greater\_equal & 是否大于等于 \\
        less           & 小于         \\
        logical\_and   & 逻辑与       \\
        logic\_not     & 逻辑取反     \\
        minus          & 减法         \\
        modulus        & 按位取余     \\
        miltiplies     & 乘法         \\
        negate         & 负数         \\
        not\_equal\_to & 不等于       \\
        plus           & 加法         \\
        \bottomrule
    \end{tabular}
\end{table}
\begin{listing}
    \cppfile{sample/functional_operator_demo.cc}
    \caption{functional 操作函数示例}
    \label{code:functional_operator_demo}
\end{listing}
\begin{table}[!htbp]
    \centering
    \caption{其它函数操作}
    \begin{tabular}{cc}
        \toprule
        函数名称                                                                                        & 说明                           \\
        \midrule
        \href{https://www.cplusplus.com/reference/functional/bad_function_call/}{bad\_function\_call}   & 空函数调用的时候抛出异常       \\
        \href{https://www.cplusplus.com/reference/functional/hash/}{hash}                               & 计算hash结果                   \\
        \href{https://www.cplusplus.com/reference/functional/is_bind_expression/}{is\_bind\_expression} & 类型T是否是 bind 的类型        \\
        \href{https://www.cplusplus.com/reference/functional/is_placeholder/}{is\_placeholder}          & 判断T是否为placeholder绑定类型 \\
        \bottomrule
    \end{tabular}
\end{table}
bad\_function\_call 返回函数调用错误异常：
\cppfile{sample/functional_bad_function_call_demo.cc}
hash函数提供了对常用对象的hash支持：
\begin{table}[!ht]
    \centering
    \begin{tabular}{|l|l|}
        \hline
        header          & 可hash类型          \\ \hline
        <functional>    & bool                \\ \hline
        ~               & char                \\ \hline
        ~               & signed char         \\ \hline
        ~               & unsigned char       \\ \hline
        ~               & char16\_t           \\ \hline
        ~               & char32\_t           \\ \hline
        ~               & wchar\_t            \\ \hline
        ~               & short               \\ \hline
        ~               & unsigned short      \\ \hline
        ~               & int                 \\ \hline
        ~               & unsigned int        \\ \hline
        ~               & long                \\ \hline
        ~               & unsigned long       \\ \hline
        ~               & long long           \\ \hline
        ~               & unsigned long long  \\ \hline
        ~               & float               \\ \hline
        ~               & double              \\ \hline
        ~               & long double         \\ \hline
        ~               & T* (for any type T) \\ \hline
        <string>        & string              \\ \hline
        ~               & wstring             \\ \hline
        ~               & u16string           \\ \hline
        ~               & u32string           \\ \hline
        <memory>        & unique\_ptr         \\ \hline
        ~               & shared\_ptr         \\ \hline
        <vector>        & vector<bool>        \\ \hline
        <bitset>        & bitset              \\ \hline
        <system\_error> & error\_code         \\ \hline
        <typeindex>     & type\_index         \\ \hline
        <thread>        & thread::id          \\ \hline
    \end{tabular}
\end{table}
is\_bind\_expression
\cppfile{sample/functional_is_bind_expression_demo.cc}
is\_placeholder：判断 \_1（1）、\_2（2）的顺序，如果placeholder已经绑定了，结果为0。
\cppfile{sample/functional_is_placeholder_demo.cc}

% 有制约算法
% C++20 在命名空间 std::ranges 中提供大多数算法的有制约版本，能以迭代器-哨位对或单个 range 参数指定范围，并且支持投影和指向成员指针可调用对象。另外更改了大多数算法的返回类型，以返回算法执行过程中计算的所有潜在有用信息。
% 
% std::vector<int> v = {7, 1, 4, 0, -1};
% std::ranges::sort(v); // 有制约算法
% 头文件 <iterator> 提供为简化常用算法操作的制约而设计的概念和工具模板集合。
% 
% (C++20 起)
% 
% 执行策略
% 大多数算法拥有接受执行策略的重载。标准算法库提供几种执行策略，并提供对应执行策略的类型和对象。用户可以静态地选择执行策略，通过以对应类型的执行策略对象为参数，调用并行算法。
% 
% 标准库实现（但不是用户）可以定义附加的执行策略作为扩展。以实现定义类型的执行策略对象调用的并行算法的语义是实现定义的。
% 
% 允许算法的并行版本（除了 std::for_each 与 std::for_each_n ）从范围进行任意的元素复制，只要 std::is_trivially_copy_constructible_v<T> 与 std::is_trivially_destructible_v<T> 均为 true ，其中 T 是元素的类型。
% 
% 定义于头文件 <execution>
% 定义于命名空间 std::execution
% sequenced_policy
% parallel_policy
% parallel_unsequenced_policy
% unsequenced_policy
%   
% (C++17)
% (C++17)
% (C++17)
% (C++20)
%  
% 执行策略类型
% (类)
% seq
% par
% par_unseq
% unseq
%   
% (C++17)
% (C++17)
% (C++17)
% (C++20)
%  
% 全局执行策略对象
% (常量)
% 定义于命名空间 std
% is_execution_policy
%   
% (C++17)
%  
% 测试一个类是否表示某种执行策略
% (类模板)
% (C++17 起)
% 不修改序列的操作
% 定义于头文件 <algorithm>
% all_of
% any_of
% none_of
%   
% (C++11)
% (C++11)
% (C++11)
%  
% 检查谓词是否对范围中所有、任一或无元素为 true
% (函数模板)
% for_each
%  
% 应用函数到范围中的元素
% (函数模板)
% for_each_n
%   
% (C++17)
%  
% 应用一个函数对象到序列的前 n 个元素
% (函数模板)
% count
% count_if
%  
% 返回满足指定判别标准的元素数
% (函数模板)
% mismatch
%  
% 寻找两个范围出现不同的首个位置
% (函数模板)
% find
% find_if
% find_if_not
%   
% (C++11)
%  
% 寻找首个满足特定判别标准的元素
% (函数模板)
% find_end
%  
% 在特定范围中寻找最后出现的元素序列
% (函数模板)
% find_first_of
%  
% 搜索元素集合中的任意元素
% (函数模板)
% adjacent_find
%  
% 查找首对相邻的相同（或满足给定谓词的）元素
% (函数模板)
% search
%  
% 搜索一个元素范围
% (函数模板)
% search_n
%  
% 在范围中搜索一定量的某个元素的连续副本
% (函数模板)
% 修改序列的操作
% 定义于头文件 <algorithm>
% copy
% copy_if
%   
% (C++11)
%  
% 将某一范围的元素复制到一个新的位置
% (函数模板)
% copy_n
%   
% (C++11)
%  
% 将一定数目的元素复制到一个新的位置
% (函数模板)
% copy_backward
%  
% 按从后往前的顺序复制一个范围内的元素
% (函数模板)
% move
%   
% (C++11)
%  
% 将某一范围的元素移动到一个新的位置
% (函数模板)
% move_backward
%   
% (C++11)
%  
% 按从后往前的顺序移动某一范围的元素到新的位置
% (函数模板)
% fill
%  
% 将一个给定值复制赋值给一个范围内的每个元素
% (函数模板)
% fill_n
%  
% 将一个给定值复制赋值给一个范围内的 N 个元素
% (函数模板)
% transform
%  
% 将一个函数应用于某一范围的各个元素，并在目标范围存储结果
% (函数模板)
% generate
%  
% 将相继的函数调用结果赋值给一个范围中的每个元素
% (函数模板)
% generate_n
%  
% 将相继的函数调用结果赋值给一个范围中的 N 个元素
% (函数模板)
% remove
% remove_if
%  
% 移除满足特定判别标准的元素
% (函数模板)
% remove_copy
% remove_copy_if
%  
% 复制一个范围的元素，忽略满足特定判别标准的元素
% (函数模板)
% replace
% replace_if
%  
% 将所有满足特定判别标准的值替换为另一个值
% (函数模板)
% replace_copy
% replace_copy_if
%  
% 复制一个范围内的元素，并将满足特定判别标准的元素替换为另一个值
% (函数模板)
% swap
%  
% 交换两个对象的值
% (函数模板)
% swap_ranges
%  
% 交换两个范围的元素
% (函数模板)
% iter_swap
%  
% 交换两个迭代器所指向的元素
% (函数模板)
% reverse
%  
% 逆转范围中的元素顺序
% (函数模板)
% reverse_copy
%  
% 创建一个范围的逆向副本
% (函数模板)
% shift_left
% shift_right
%   
% (C++20)
%  
% 迁移范围中的元素
% (函数模板)
% rotate
%  
% 旋转范围中的元素顺序
% (函数模板)
% rotate_copy
%  
% 复制并旋转元素范围
% (函数模板)
% random_shuffle
% shuffle
%   
% (C++17 前)
% (C++11)
%  
% 随机重排范围中的元素
% (函数模板)
% sample
%   
% (C++17)
%  
% 从一个序列中随机选择 n 个元素
% (函数模板)
% unique
%  
% 移除范围内的连续重复元素
% (函数模板)
% unique_copy
%  
% 创建某范围的不含连续重复元素的副本
% (函数模板)
% 划分操作
% 定义于头文件 <algorithm>
% is_partitioned
%   
% (C++11)
%  
% 判断范围是否已按给定的谓词划分
% (函数模板)
% partition
%  
% 将范围中的元素分为两组
% (函数模板)
% partition_copy
%   
% (C++11)
%  
% 复制一个范围，将各元素分为两组
% (函数模板)
% stable_partition
%  
% 将元素分为两组，同时保留其相对顺序
% (函数模板)
% partition_point
%   
% (C++11)
%  
% 定位已划分范围的划分点
% (函数模板)
% 排序操作
% 定义于头文件 <algorithm>
% is_sorted
%   
% (C++11)
%  
% 检查范围是否已按升序排列
% (函数模板)
% is_sorted_until
%   
% (C++11)
%  
% 找出最大的已排序子范围
% (函数模板)
% sort
%  
% 将范围按升序排序
% (函数模板)
% partial_sort
%  
% 排序一个范围的前 N 个元素
% (函数模板)
% partial_sort_copy
%  
% 对范围内的元素进行复制并部分排序
% (函数模板)
% stable_sort
%  
% 将范围内的元素排序，同时保持相等的元素之间的顺序
% (函数模板)
% nth_element
%  
% 将给定的范围部分排序，确保其按给定元素划分
% (函数模板)
% 二分搜索操作（在已排序范围上）
% 定义于头文件 <algorithm>
% lower_bound
%  
% 返回指向第一个不小于给定值的元素的迭代器
% (函数模板)
% upper_bound
%  
% 返回指向第一个大于给定值的元素的迭代器
% (函数模板)
% binary_search
%  
% 确定元素是否存在于某范围中
% (函数模板)
% equal_range
%  
% 返回匹配特定键值的元素范围
% (函数模板)
% 集合操作（在已排序范围上）
% 定义于头文件 <algorithm>
% merge
%  
% 归并两个已排序的范围
% (函数模板)
% inplace_merge
%  
% 就地归并两个有序范围
% (函数模板)
% includes
%  
% 若一个集合是另一个的子集则返回 true
% (函数模板)
% set_difference
%  
% 计算两个集合的差集
% (函数模板)
% set_intersection
%  
% 计算两个集合的交集
% (函数模板)
% set_symmetric_difference
%  
% 计算两个集合的对称差
% (函数模板)
% set_union
%  
% 计算两个集合的并集
% (函数模板)
% 堆操作
% 定义于头文件 <algorithm>
% is_heap
%  
% 检查给定范围是否为一个最大堆
% (函数模板)
% is_heap_until
%   
% (C++11)
%  
% 查找能成为最大堆的最大子范围
% (函数模板)
% make_heap
%  
% 从一个元素范围创建出一个最大堆
% (函数模板)
% push_heap
%  
% 将一个元素加入到一个最大堆
% (函数模板)
% pop_heap
%  
% 从最大堆中移除最大元素
% (函数模板)
% sort_heap
%  
% 将一个最大堆变成一个按升序排序的元素范围
% (函数模板)
% 最小/最大操作
% 定义于头文件 <algorithm>
% max
%  
% 返回各给定值中的较大者
% (函数模板)
% max_element
%  
% 返回范围内的最大元素
% (函数模板)
% min
%  
% 返回各给定值中的较小者
% (函数模板)
% min_element
%  
% 返回范围内的最小元素
% (函数模板)
% minmax
%   
% (C++11)
%  
% 返回两个元素的较小和较大者
% (函数模板)
% minmax_element
%   
% (C++11)
%  
% 返回范围内的最小元素和最大元素
% (函数模板)
% clamp
%   
% (C++17)
%  
% 在一对边界值间夹逼一个值
% (函数模板)
% 比较操作
% 定义于头文件 <algorithm>
% equal
%  
% 确定两个元素集合是否是相同的
% (函数模板)
% lexicographical_compare
%  
% 当一个范围按字典顺序小于另一个范围时，返回 true
% (函数模板)
% lexicographical_compare_three_way
%   
% (C++20)
%  
% 用三路比较比较两个范围
% (函数模板)
% 排列操作
% 定义于头文件 <algorithm>
% is_permutation
%   
% (C++11)
%  
% 判断一个序列是否为另一个序列的排列
% (函数模板)
% next_permutation
%  
% 产生某个元素范围的按字典顺序的下一个较大的排列
% (函数模板)
% prev_permutation
%  
% 产生某个元素范围的按字典顺序的下一个较小的排列
% (函数模板)
% 数值运算
% 定义于头文件 <numeric>
% iota
%   
% (C++11)
%  
% 用从起始值开始连续递增的值填充一个范围
% (函数模板)
% accumulate
%  
% 对一个范围内的元素求和
% (函数模板)
% inner_product
%  
% 计算两个范围的元素的内积
% (函数模板)
% adjacent_difference
%  
% 计算范围内各相邻元素之间的差
% (函数模板)
% partial_sum
%  
% 计算范围内元素的部分和
% (函数模板)
% reduce
%   
% (C++17)
%  
% 类似 std::accumulate，但不依序执行
% (函数模板)
% exclusive_scan
%   
% (C++17)
%  
% 类似 std::partial_sum，第 i 个和中排除第 i 个输入
% (函数模板)
% inclusive_scan
%   
% (C++17)
%  
% 类似 std::partial_sum，第 i 个和中包含第 i 个输入
% (函数模板)
% transform_reduce
%   
% (C++17)
%  
% 应用一个函数对象，然后以乱序规约
% (函数模板)
% transform_exclusive_scan
%   
% (C++17)
%  
% 应用一个函数对象，然后进行排除扫描
% (函数模板)
% transform_inclusive_scan
%   
% (C++17)
%  
% 应用一个函数对象，然后进行包含扫描
% (函数模板)
% 未初始化内存上的操作
% 定义于头文件 <memory>
% uninitialized_copy
%  
% 将范围内的对象复制到未初始化的内存区域
% (函数模板)
% uninitialized_copy_n
%   
% (C++11)
%  
% 将指定数量的对象复制到未初始化的内存区域
% (函数模板)
% uninitialized_fill
%  
% 复制一个对象到以范围定义的未初始化内存区域
% (函数模板)
% uninitialized_fill_n
%  
% 复制一个对象到以起点和计数定义的未初始化内存区域
% (函数模板)
% uninitialized_move
%   
% (C++17)
%  
% 移动一个范围的对象到未初始化的内存区域
% (函数模板)
% uninitialized_move_n
%   
% (C++17)
%  
% 移动一定数量对象到未初始化内存区域
% (函数模板)
% uninitialized_default_construct
%   
% (C++17)
%  
% 在范围所定义的未初始化的内存区域以默认初始化构造对象
% (函数模板)
% uninitialized_default_construct_n
%   
% (C++17)
%  
% 在起始和计数所定义的未初始化内存区域用默认初始化构造对象
% (函数模板)
% uninitialized_value_construct
%   
% (C++17)
%  
% 在范围所定义的未初始化内存中用值初始化构造对象
% (函数模板)
% uninitialized_value_construct_n
%   
% (C++17)
%  
% 在起始和计数所定义的未初始化内存区域以值初始化构造对象
% (函数模板)
% destroy_at
%   
% (C++17)
%  
% 销毁在给定地址的对象
% (函数模板)
% destroy
%   
% (C++17)
%  
% 销毁一个范围中的对象
% (函数模板)
% destroy_n
%   
% (C++17)
%  
% 销毁范围中一定数量的对象
% (函数模板)
% C 库
% 定义于头文件 <cstdlib>
% qsort
%  
% 对未指定类型的元素的一个范围进行排序
% (函数)
% bsearch
%  
% 在未指定类型的数组中搜索元素

% (函数)
